package com.min.gps.service;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.min.gps.model.DataCode;
import com.min.gps.model.GPSInfo;
import com.min.gps.model.LoraInfo;
import com.min.gps.util.ByteUtils;
import com.min.gps.util.*;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

import java.io.*;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;
import java.util.concurrent.*;

public class DataServer implements Runnable {
     Logger log = LogManager.getLogger(DataServer.class);
    private boolean close = false; // 关闭连接标志位，true表示关闭，false表示连接
    BackClient backClient =new BackClient();
    private static Socket socket;
    public void startServer() {

        //服务端在20006端口监听客户端请求的TCP连接
        ServerSocket server = null;
        try {
            server = new ServerSocket(1122, 10000);
            ExecutorService pool = new ThreadPoolExecutor(0, 10,
                    20L, TimeUnit.SECONDS,
                    new SynchronousQueue<>());
                 while (true) {
                //等待客户端的连接，如果没有获取连接
                 socket = server.accept();
                //为每个客户端连接开启一个线程
                pool.execute(new DataServer(socket));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }


    }

    public DataServer(Socket socket) throws IOException {
        this.socket = socket;
    }

    @Override
    public void run() {
            while (true) {//保持长连接
             if (socket != null) {
                DataInputStream input = null;
                DataOutputStream out = null;
                //---------读数据---------------------------
                close = isServerClose(socket);//判断是否断开,心跳
               if(!close){
                try {
                    socket.setKeepAlive(true);
                    input = new DataInputStream(socket.getInputStream());
                    out = new DataOutputStream(socket.getOutputStream());
                    byte[] buff = new byte[1024];
                    input.read(buff);
                    int type = buff[6];
                    byte[] lengthData = new byte[2];//数据长度
                    System.arraycopy(buff, 1, lengthData, 0, 2);
                    byte[] cityID = new byte[2];//车辆ID
                    System.arraycopy(buff, 4, cityID, 0, 2);
                    int datalength = Integer.parseInt(ByteUtils.bytesToHexString(lengthData), 16);//字节数组转十进制
                    int crclength = datalength + 4;
                    byte[] crxData = new byte[crclength];//校验数据
                    System.arraycopy(buff, 0, crxData, 0, crclength);
                    byte[] Data = new byte[datalength - 3];//解析数据
                    System.arraycopy(buff, 7, Data, 0, Data.length);
                    byte[] cxcCode = new byte[2];
                    System.arraycopy(buff, crclength, cxcCode, 0, 2);
                    String checkCode = String.format("%04x", CRC16Util.calcCrc16(crxData)).toUpperCase();
                    if (ByteUtils.bytesToHexString(cxcCode).equals(checkCode)) {//crc16校验
                        if (type == 1) {//GPS数据解析
                             GPSInfo parseData = new GPSInfo();
                            String tempdata = new String(Data);
                            String gpsArray[] = tempdata.split(",");
                            parseData.setCityID(ByteUtils.bytesToHexString(cityID));
                            parseData.setSendTime(DateUtil.getNowDateTime());
                            parseData.setDataFormat(gpsArray[0]);
                            parseData.setStatus(gpsArray[2]);
                            parseData.setGPSTime(GpsUtil.posDate(gpsArray[9]) + GpsUtil.posTime(gpsArray[1]));
                            parseData.setLatitude(GpsUtil.hemisphere(gpsArray[4]) + GpsUtil.latitude(gpsArray[3]));
                            parseData.setLongitude(GpsUtil.hemisphere(gpsArray[6]) + GpsUtil.longitude(gpsArray[5]));
                            parseData.setSpeed(gpsArray[7]);
                            parseData.setHeading(gpsArray[8]);
                            parseData.setMagneticDeclination(gpsArray[10]);
                            parseData.setMagneticDirection(gpsArray[11]);
                           // GPSService dataService = (GPSService) SpringContextUtil.getBean("GPSService");
                           // dataService.save(parseData);
                            //gps数据解析后推送到web端
                            JSONObject result= new JSONObject();
                            result.put("data",JSON.toJSONString(parseData) );
                            HttpRequestUtils.httpPost("http://localhost:9001/send",  result, false);
                            //out.writeUTF(JSON.toJSONString(parseData));
                           // out.flush();
                        }
                        if (type == 2) {//Lora数据解析
                            List<DataCode> listCode = new ArrayList<>();
                            for (int i = 0; i < Data.length / 6; i++) {
                                byte[] array = Arrays.copyOfRange(Data, 6 * i, 6 * i + 6);
                                byte[] checkArray = new byte[5];
                                System.arraycopy(array, 0, checkArray, 0, 5);
                                byte[] ByteCode = new byte[3];
                                System.arraycopy(array, 1, ByteCode, 0, 3);
                                if (array[5] == ByteUtils.checkByte(checkArray)) {
                                    DataCode dataCode = new DataCode();
                                    dataCode.setByteCode(ByteUtils.bytesToHexString(ByteCode));
                                    listCode.add(dataCode);
                                }
                            }
                            LoraInfo parseData = new LoraInfo();
                            parseData.setCityID(ByteUtils.bytesToHexString(cityID));
                            parseData.setSendTime(DateUtil.getNowDateTime());
                            parseData.setDataList(listCode);
                         //  LoraService dataService = (LoraService) SpringContextUtil.getBean("LoraService");
                         //  dataService.save(parseData);
                            //lora数据解析后通过socketClient推送到后端服务（断开需自动重连）
                            backClient.sendMessage(JSON.toJSONString(parseData));
                           // out.writeUTF(JSON.toJSONString(parseData));
                          //  out.flush();
                        }
                    }
                } catch (Exception e) {
                    e.printStackTrace();
                }
                }
            }
        }
    }
    /**
     * 判断是否断开连接，断开返回true,没有返回false
     * @param socket
     * @return
     */
    public Boolean isServerClose(Socket socket){
        try{
            socket.sendUrgentData(0xFF);//发送1个字节的紧急数据，默认情况下，服务器端没有开启紧急数据处理，不影响正常通信
            return false;
        }catch(Exception se){
            return true;
        }
    }
    public static void main(String[] args) throws IOException {
        DataServer server = new DataServer(socket);
        server.startServer();
    }
}
